package com.ukefu.webim.web.handler;

import com.ukefu.core.UKDataContext;
import com.ukefu.util.Menu;
import com.ukefu.util.UKTools;
import com.ukefu.util.VerifyCodeUtils;
import com.ukefu.webim.service.repository.*;
import com.ukefu.webim.web.model.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.imageio.ImageIO;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 *
 * @author UK
 * @version 1.0.0
 *
 */
@Controller
public class LoginController extends Handler{
	
	@Autowired
	private UserRepository userRepository;
	
	@Autowired
	private OrganRoleRepository organRoleRes ;
	
	@Autowired
	private UserRoleRepository userRoleRes ;
	
	@Autowired
	private RoleAuthRepository roleAuthRes ;
	
	@Autowired
	private OrganRepository organRepository;

	@Autowired
	private TenantRepository tenantRes;//租户表

    @RequestMapping(value = "/login" , method=RequestMethod.GET)
    @Menu(type = "apps" , subtype = "user" , access = true)
    public ModelAndView login(HttpServletRequest request, HttpServletResponse response  , @RequestHeader(value = "referer", required = false) String referer , @Valid String msg) throws NoSuchAlgorithmException {
    	ModelAndView view = request(super.createRequestPageTempletResponse("redirect:/"));
    	if(request.getSession(true).getAttribute(UKDataContext.USER_SESSION_NAME) ==null){
    		view = request(super.createRequestPageTempletResponse("/login"));
	    	if(!StringUtils.isBlank(request.getParameter("referer"))){
	    		referer = request.getParameter("referer") ;
	    	}
	    	if(!StringUtils.isBlank(referer)){
	    		view.addObject("referer", referer) ;
	    	}
	    	Cookie[] cookies = request.getCookies();//这样便可以获取一个cookie数组
	    	if(cookies!=null) {
	    		for(Cookie cookie : cookies){
					if(cookie!=null && !StringUtils.isBlank(cookie.getName()) && !StringUtils.isBlank(cookie.getValue())){
						if(cookie.getName().equals(UKDataContext.UKEFU_SYSTEM_COOKIES_FLAG)){
							String flagid = UKTools.decryption(cookie.getValue());
							if(!StringUtils.isBlank(flagid)) {
								User user = userRepository.findByIdAndOrgi(flagid,super.getOrgi(request)) ;
								if(user!=null) {
									view = this.processLogin(request, response, view, user, referer) ;
								}
							}
						}
					}
				}
	    	}
    	}
    	if(!StringUtils.isBlank(msg)){
    		view.addObject("msg", msg) ;
    	}
    	SystemConfig systemConfig = UKTools.getSystemConfig();
    	if(systemConfig!=null&&systemConfig.isEnableregorgi()) {
    		view.addObject("show", true);
    	}
		if(systemConfig != null){
			view.addObject("systemConfig", systemConfig)  ;
		}
        return view;
    }
    
    @RequestMapping(value = "/login" , method=RequestMethod.POST)
    @Menu(type = "apps" , subtype = "user" , access = true)
    public ModelAndView login(HttpServletRequest request, HttpServletResponse response , @Valid User user ,@Valid String code,@Valid String referer,@Valid String sla) throws NoSuchAlgorithmException {
    	ModelAndView view = request(super.createRequestPageTempletResponse("redirect:/"));
    	if(request.getSession(true).getAttribute(UKDataContext.USER_SESSION_NAME) ==null){
    		String attcode = (String) request.getSession().getAttribute(UKDataContext.CODE_SESSION_NAME) ;
    		SystemConfig systemConfig = UKTools.getSystemConfig();
	        if(user!=null && !StringUtils.isBlank(user.getUsername()) && !StringUtils.isBlank(user.getPassword()) && (systemConfig.isVcode() == false || (!StringUtils.isBlank(code) && code.equalsIgnoreCase(attcode)))){
	        	request.getSession().removeAttribute(UKDataContext.CODE_SESSION_NAME);
	        	final User loginUser = userRepository.findByUsernameAndPasswordAndDatastatus(user.getUsername() , UKTools.md5(user.getPassword()),false) ;
		        if(loginUser!=null && !StringUtils.isBlank(loginUser.getId())){
		        	loginUser.setClientip(user.getClientip());
		        	view = this.processLogin(request, response, view, loginUser, referer) ;
		        	
		        	if (!StringUtils.isBlank(sla) && sla.equals("1") && systemConfig.isRemember()) {
                        Cookie flagid = new Cookie(UKDataContext.UKEFU_SYSTEM_COOKIES_FLAG, UKTools.encryption(loginUser.getId()));
                        flagid.setMaxAge(7 * 24 * 60 * 60);
                        response.addCookie(flagid);
                    }
		        }else{
		        	view = request(super.createRequestPageTempletResponse("/login"));
		        	if(!StringUtils.isBlank(referer)){
			    		view.addObject("referer", referer) ;
			    	}
		        	view.addObject("msg", "0") ;
		        }
	        }else {
	        	view = request(super.createRequestPageTempletResponse("/login"));
	        	view.addObject("msg", "10") ;
	        }
    	}
    	SystemConfig systemConfig = UKTools.getSystemConfig();
    	if(systemConfig!=null&&systemConfig.isEnableregorgi()) {
    		view.addObject("show", true);
    	}
    	if(systemConfig != null){
			view.addObject("systemConfig", systemConfig)  ;
		}
    	return view;
    }
    
    @RequestMapping(value = "/code" , method=RequestMethod.GET)
    @Menu(type = "apps" , subtype = "user" , access = true)
    public void code(HttpServletRequest req, HttpServletResponse resp , @Valid User user ,@Valid String referer,@Valid String sla) throws NoSuchAlgorithmException {
    	// 调用工具类生成的验证码和验证码图片
        Map<String, Object> codeMap = VerifyCodeUtils.generateCodeAndPic();

        // 将四位数字的验证码保存到Session中。
        HttpSession session = req.getSession();
        if(session.getAttribute(UKDataContext.CODE_SESSION_NAME) != null) {
        	session.removeAttribute(UKDataContext.CODE_SESSION_NAME) ;
        }
        session.setAttribute(UKDataContext.CODE_SESSION_NAME, codeMap.get("code").toString());

        // 禁止图像缓存。
        resp.setHeader("Pragma", "no-cache");
        resp.setHeader("Cache-Control", "no-cache");
        resp.setDateHeader("Expires", -1);

        resp.setContentType("image/jpeg");

        // 将图像输出到Servlet输出流中。
        ServletOutputStream sos;
        try {
            sos = resp.getOutputStream();
            ImageIO.write((RenderedImage) codeMap.get("codePic"), "jpeg", sos);
            sos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public ModelAndView processLogin(HttpServletRequest request, HttpServletResponse response , ModelAndView view  ,final User loginUser , String referer) {
    	if(loginUser!=null) {
	    	loginUser.setLogin(true);
	    	if(!StringUtils.isBlank(referer)){
	    		view = request(super.createRequestPageTempletResponse("redirect:"+referer));
	    	}else {
	    		view = request(super.createRequestPageTempletResponse("redirect:/"));
	    	}
	    	//登录成功 判断是否进入多租户页面
	    	SystemConfig systemConfig = UKTools.getSystemConfig();
	    	//开启多租户 判断多租户是否锁定
			if(systemConfig!=null&&systemConfig.isEnabletneant()) {
				Tenant tenant = tenantRes.findByTenantcode(loginUser.getOrgi());
				if((tenant == null || (tenant != null && tenant.isDatastatus())) && !UKDataContext.SYSTEM_ORGI.equals(loginUser.getOrgi())){
					view = request(super.createRequestPageTempletResponse("/login"));
					view.addObject("msg", "11") ;
					return view;
				}
			}
			view.addObject("msg", "0") ;

	    	if(systemConfig!=null&&systemConfig.isEnabletneant() && systemConfig.isTenantconsole() &&!loginUser.isSuperuser()) {
	    		view = request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index"));
	    	}
	    	List<UserRole> userRoleList = userRoleRes.findByOrgiAndUser(loginUser.getOrgi(), loginUser);
	    	if(userRoleList!=null && userRoleList.size()>0){
	    		for(UserRole userRole : userRoleList){
	    			loginUser.getRoleList().add(userRole.getRole()) ;
	    		}
	    	}
	    	if(!StringUtils.isBlank(loginUser.getOrgan())){
	    		Organ organ = organRepository.findByIdAndOrgi(loginUser.getOrgan(), loginUser.getOrgi()) ;
	    		if(organ!=null){
	    			List<OrganRole> organRoleList = organRoleRes.findByOrgiAndOrgan(loginUser.getOrgi(), organ) ;
	    			if(organRoleList.size() > 0){
	    				for(OrganRole organRole : organRoleList){
	    					loginUser.getRoleAuthMap().put(organRole.getDicvalue(),true);
	    				}
	    			}
	    		}
	    	}
	    	//获取用户的授权资源
	    	List<RoleAuth> roleAuthList = roleAuthRes.findAll(new Specification<RoleAuth>(){
	    		@Override
	    		public Predicate toPredicate(Root<RoleAuth> root, CriteriaQuery<?> query,
	    				CriteriaBuilder cb) {
	    			List<Predicate> list = new ArrayList<Predicate>();  
	    			if(loginUser.getRoleList()!=null && loginUser.getRoleList().size() > 0){
	    				for(Role role : loginUser.getRoleList()){
	    					list.add(cb.equal(root.get("roleid").as(String.class), role.getId())) ;
	    				}
	    			}
	    			Predicate[] p = new Predicate[list.size()];  
	    			cb.and(cb.equal(root.get("orgi").as(String.class), loginUser.getOrgi())) ;
	    			return cb.or(list.toArray(p));  
	    		}}) ;
	    	if(roleAuthList!=null) {
	    		for(RoleAuth roleAuth:roleAuthList) {
	    			loginUser.getRoleAuthMap().put(roleAuth.getDicvalue(), true);
	    		}
	    	}
	
	    	loginUser.setLastlogintime(new Date());
	    	if(!StringUtils.isBlank(loginUser.getId())){
	    		userRepository.save(loginUser) ;
	    	}
	    	super.setUser(request, loginUser);
	    	//当前用户 企业id为空 调到创建企业页面
        	if(StringUtils.isBlank(loginUser.getOrgid())) {
        		view = request(super.createRequestPageTempletResponse("redirect:/apps/organization/add.html"));
        	}
    	}
    	return view ;
    }

    @RequestMapping("/logout")  
    public String logout(HttpServletRequest request  , HttpServletResponse response){  
    	request.getSession().removeAttribute("Utoken") ;
    	request.getSession().removeAttribute(UKDataContext.USER_SESSION_NAME) ;
		request.getSession().removeAttribute(UKDataContext.SUPERUSER_LOGIN_SESSION_NAME) ;
    	request.getSession().invalidate();
    	Cookie[] cookies = request.getCookies();
    	if(cookies!=null) {
    		for(Cookie cookie : cookies){
				if(cookie!=null && !StringUtils.isBlank(cookie.getName()) && !StringUtils.isBlank(cookie.getValue())){
					if(cookie.getName().equals(UKDataContext.UKEFU_SYSTEM_COOKIES_FLAG)){
						cookie.setMaxAge(0);
						response.addCookie(cookie);
					}
				}
			}
    	}
        return "redirect:/";
    }
}